import type { VbenFormSchema } from '#/adapter/form'

import { computed, getCurrentInstance, ref, toRaw, unref } from 'vue'
import type { Ref } from 'vue'

import { useVbenDrawer, useVbenForm, useVbenModal } from '@vben/common-ui'
import { IconifyIcon } from '@vben/icons'
import { isEmpty, isFunction } from '@vben/utils'

import { Image, ImagePreviewGroup, message, Tag } from 'ant-design-vue'

import { getOptionsLabelByValue } from '#/config/options/utils'
import { findNode } from '#/helper/treeHelper'
import { $t } from '@vben/locales'

type Recordable<T = any> = Record<string, T>

/**
 * 添加编辑表单
 */
export function useAddEditForm<T extends Recordable>(opts?: {
    addText?: string
    editText?: string
    onAddSubmit?: (values: T) => Promise<any>
    onBeforeSubmit?: () => boolean | Promise<boolean>
    onEditSubmit?: (opts: {
        rowId: number | string
        values: T & {
            id?: any
        }
    }) => Promise<any>
    onFinish?: () => void
    onSuccess?: (values: {
        isUpdate: boolean
        values: T & {
            id?: any
        }
    }) => void
    title?: Ref<string> | string
    useFormParams?: Parameters<typeof useVbenForm>[0]
    viewText?: string
}) {
    type ValuesType = T & {
        id?: null | number | string
    }
    const {
        title = '',
        onEditSubmit,
        onAddSubmit,
        onSuccess,
        onFinish,
        onBeforeSubmit,
        addText = 'common.formModal.addTitle',
        editText = 'common.formModal.editTitle',
        viewText = 'common.formModal.viewTitle',
        useFormParams
    } = opts ?? {}

    const currentInstance = getCurrentInstance()

    const rowId = ref<null | number | string>(null)
    // 是否查看模式
    const isViewMode = ref(false)
    // 是否是编辑
    const isUpdate = computed(() => !isEmpty(rowId.value))

    const formTitle = computed(() => {
        const text = isUpdate.value ? editText : addText

        return $t(isViewMode.value ? viewText : text, {
            title: unref(title)
        })

        // return `${isViewMode.value ? viewText : text}${title}`;
    })

    // const isXsScreen = useMediaQuery('(max-width: 768px)')

    const [Form, formApi] = useVbenForm({
        handleSubmit,
        schema: [],
        showDefaultActions: false,
        layout: 'vertical', // isXsScreen.value ? 'vertical' : 'horizontal',
        wrapperClass: 'grid-cols-1 md:grid-cols-2 gap-x-4',
        ...useFormParams
    })

    const _setState = formApi.setState

    formApi.setState = (data: Parameters<typeof _setState>[0]) => {
        if (!isFunction(data) && data.schema) {
            setSchema(data.schema)
        }
        _setState(data)
    }

    // 通用属性
    function setSchema(schema: Ref<VbenFormSchema[]> | VbenFormSchema[]) {
        const arr = unref(schema)
        arr.forEach((item) => {
            switch (item.component) {
                case 'Divider': {
                    // item.formItemClass += ' pt-6'
                    item.labelWidth = item.labelWidth || undefined
                    item.labelClass = item.labelClass || 'text-lg font-medium'
                    break
                }
            }
        })

        return schema
    }

    async function handleSubmit() {
        try {
            const ret = await formApi.validate()
            if (!ret.valid) return
            const values = toRaw(await formApi.getValues()) as ValuesType

            Object.keys(values).forEach((key) => {
                // 日历格式
                if (key.includes(',')) {
                    delete values[key]
                }
            })

            if (onBeforeSubmit) {
                const flag = await onBeforeSubmit()

                if (!flag) return
            }

            if (isUpdate.value) {
                if (rowId.value && typeof onEditSubmit === 'function') {
                    await onEditSubmit({
                        rowId: rowId.value,
                        values
                    })
                    message.success($t('common.editSuccess'))
                }
            } else {
                if (typeof onAddSubmit === 'function') {
                    await onAddSubmit(values)
                    message.success($t('common.createSuccess'))
                }
            }

            const eventParams = {
                isUpdate: unref(isUpdate),
                values: { ...values, id: rowId.value }
            }
            onSuccess && onSuccess(eventParams)
            currentInstance?.emit('success', eventParams)
        } finally {
            if (onFinish) {
                onFinish()
            }
        }
    }

    function setViewMode(val: boolean) {
        isViewMode.value = val
    }

    function setRowId(id: null | number | string) {
        rowId.value = id
    }

    return {
        Form,
        formApi,
        formTitle,
        setViewMode,
        setRowId,
        isViewMode,
        isUpdate,
        handleSubmit
    }
}

/**
 * 弹窗表单
 */
export function useAddEditFormModal<T extends Recordable>(opts: {
    formApi: ReturnType<typeof useVbenForm>[1]
    modalType?: 'drawer' | 'modal'
    onOpen?: (data: Record<string, any>) => void
    useModalParams?: Parameters<typeof useVbenDrawer>[0] & Parameters<typeof useVbenModal>[0]
}) {
    const { formApi, onOpen, useModalParams, modalType = 'modal' } = opts

    const modalParmas = {
        fullscreenButton: false,
        class: 'w-[800px] ',
        contentClass: 'p-6',
        onCancel() {
            modalApi.close()
        },
        onConfirm: async () => {
            const ret = await formApi.validate()

            if (ret.valid) {
                modalApi.setState({
                    confirmLoading: true
                })
                try {
                    await formApi.submitForm()
                    modalApi.close()
                } catch {}
                modalApi.setState({
                    confirmLoading: false
                })
            }
        },
        onOpenChange(isOpen: boolean) {
            if (isOpen) {
                formApi.resetForm()
                if (onOpen) {
                    onOpen(modalApi.getData<Record<string, any>>())
                }
            }
        },
        ...useModalParams
    }

    const [Modal, modalApi] =
        modalType === 'modal' ? useVbenModal<T>(modalParmas) : useVbenDrawer<T>(modalParmas)

    return {
        Modal,
        modalApi
    }
}

export function transformFormSchema<T extends VbenFormSchema[]>(schema: T) {
    schema.forEach((item) => {
        const label: string = unref(item.label ?? '') as string

        if (
            item.component !== 'Divider' &&
            label &&
            !(label.endsWith(':') || label.endsWith('：'))
        ) {
            item.label = `${label}:`
        }

        if (item.rules) {
            item.rules = null
        }
        if (item.help) {
            item.help = ''
        }
        // 部分设置了宽度 和 后缀显示 详情页需要去掉
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        if (item.suffix && item.componentProps?.style) {
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            item.componentProps.style += ' width: auto'
        }

        item.formItemClass = `${item.formItemClass} items-start`

        switch (item.component) {
            case 'DatePicker':
            case 'Input':
            case 'InputNumber':
            case 'InputPassword':
            case 'InputTextArea':
            case 'Textarea': {
                item.component = formReadonlyRender
                break
            }

            case 'IconPicker': {
                item.component = (vm) => {
                    const { modelValue } = vm

                    return (
                        <div class="flex">
                            <IconifyIcon class="mr-1" height="20px" icon={modelValue}></IconifyIcon>
                            {modelValue}
                        </div>
                    )
                }

                break
            }

            case 'ImageUpload': {
                item.component = (vm) => {
                    const { modelValue } = vm
                    let arr = modelValue || []

                    if (typeof arr === 'string') {
                        arr = arr.split(',')
                    }
                    return (
                        <ImagePreviewGroup>
                            <div class="flex flex-wrap gap-2">
                                {' '}
                                {arr.map((v: string) => {
                                    return <Image height={100} src={v} width={100} />
                                })}
                            </div>
                        </ImagePreviewGroup>
                    )
                }
                break
            }

            case 'RadioGroup':
            case 'Select': {
                item.component = (vm) => {
                    const val = vm.modelValue
                    const valArr = Array.isArray(val) ? val : [val]
                    const arr = isEmpty(val) ? [] : valArr

                    const { options, mode } = vm

                    const arr2 = options?.length
                        ? arr.map((v) => getOptionsLabelByValue(v, vm.options) || v)
                        : arr
                    const isTag = mode === 'tags'
                    return formCellRender(arr2.map((v) => (isTag ? <Tag>{v}</Tag> : v)))
                }
                break
            }

            case 'Switch': {
                item.component = (vm) => {
                    const flag = vm.modelValue === vm.checkedValue
                    console.log(flag, vm)
                    return (
                        <Tag color={flag ? 'success' : 'rgba(9, 9, 11, 0.25)'}>
                            {flag ? vm.checkedChildren : vm.unCheckedChildren}
                        </Tag>
                    )
                }
                break
            }
            case 'TableSelect': {
                item.component = (vm) => {
                    const { componentProps } = item as any

                    const val = vm.modelValue
                    const labelKey = componentProps?.labelKey || 'name'
                    const rowKey = componentProps?.rowKey || 'id'
                    const valArr = Array.isArray(val) ? val : [val]
                    const arr = isEmpty(val) ? [] : valArr
                    const options = (vm?.options || []).map((v2: any) => {
                        return {
                            value: v2[rowKey],
                            label: v2[labelKey]
                        }
                    })
                    return formCellRender(`${arr.map((v) => getOptionsLabelByValue(v, options))}`)
                }
                break
            }
            case 'Tinymce': {
                item.componentProps = {
                    ...item.componentProps,
                    disabled: true
                }
                break
            }

            case 'TreeSelect': {
                item.component = (vm) => {
                    const { modelValue, treeData, fieldNames } = vm

                    const curNode = findNode(
                        treeData || [],
                        (node) => {
                            return modelValue === node[fieldNames?.value || 'id']
                        },
                        fieldNames
                    )

                    const val = curNode?.[fieldNames?.label || 'title']

                    return isEmpty(val) ? '' : val
                }
                break
            }
        }
    })

    return schema
}

/**
 * 表单纯显示
 */
export function formReadonlyRender(vm: any) {
    return formCellRender(vm.modelValue)
}

export function formCellRender(text: any) {
    return (
        <div class="break-all leading-6" style="font-size:14px">
            {text}
        </div>
    )
}
